/*
 * Copyright 2004 original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jbfilter.impl;

import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.jbfilter.core.fcomps.single.SingleFilterComponent;

abstract class _SingleFilterComponentHibernateSupport<E, T, C extends SingleFilterComponent<E, T>>
	extends _FilterComponentHibernateSupport<E, C> {
	// defaults to false
	private boolean nullTestingEnabled = false;
	private String propertyPath;
	
	_SingleFilterComponentHibernateSupport(C filterComponent) {
		super(filterComponent);
	}

	public void setNullTestingEnabled(boolean enabled) {
		this.nullTestingEnabled = enabled;
	}

	public boolean isNullTestingEnabled() {
		return nullTestingEnabled;
	}

	public String getPropertyPath() {
		if (propertyPath != null) {
			return propertyPath;
		} else {
			return getFilterComponent().getId();
		}
	}

	public void setPropertyPath(String propertyPath) {
		this.propertyPath = propertyPath;
	}
	@Override
	protected Criterion buildCriterion() {
		String propertyPath = getPropertyPath();
		if(propertyPath == null) {
			throw new IllegalStateException("propertyPath is null.");
		}
		T value = getFilterComponent().getValue();
		Criterion nullTestingCriterion = getNullTestingCriterion(value);
		if (nullTestingCriterion != null) {
			return nullTestingCriterion;
		} 
		if (value == null) {
			return null; // ignore filter components which values null, otherwise all the filter would get pointless in this case
		}
		return buildCriterionCallBackFromSFCSupport(propertyPath, value);
	}
	
	protected Criterion getNullTestingCriterion(T value) {
		if (isNullTestingEnabled() && value == null) {
			return Restrictions.isNull(getPropertyPath());
		} else {
			return null;
		}
	}
	
	abstract protected Criterion buildCriterionCallBackFromSFCSupport(String propertyPath, T value);
}
